<template>
  <div class="dynamic-tags">
    <draggable :component-data="{ tag: 'div', name: 'flip-list', type: 'transition' }"
               :list="dynamicTags"
               item-key="order_num"
               tag="transition-group"
               v-bind="dragOptions">
      <template #item="{ element: item, index }">
        <div :key="item.order_num + (item.id * 1000)" class="dynamic-item">
          <el-input v-model="item.item" :readonly="disabled" class="dynamic-tag"/>
          <span v-if="!disabled && item.id == 0" class='close-icon' @click="handleDelete(item)"/>
        </div>
      </template>
    </draggable>

    <div v-if="!disabled" class="dynamic-item">
      <el-input v-if="inputVisible" ref="addInputRef"
                v-model="inputValue"
                class="dynamic-tag-add"
                @blur="handleAddInputConfirm"
                @keyup.enter.native="handleAddInputConfirm">
      </el-input>
      <el-button v-else class="button-add-tag" icon="circle-plus" plain @click="handleShowAddInput">添加</el-button>
    </div>
  </div>
</template>

<script lang="ts" setup>
import draggable from '@/components/vuedraggable/src/vuedraggable';
import { computed, nextTick, PropType, ref } from 'vue';
import { DynamicItem } from './types.ts';

defineOptions({name: 'DynamicTags'})

const props = defineProps({
  dynamicTags: {
    type: Array as PropType<DynamicItem[]>,
    default: () => [],
    required: true
  },
  disabled: {
    type: Boolean,
    default: false
  },
  maxWidth: {
    type: String,
    default: '120px'
  },
})

const dragOptions = computed(() => {
  return {
    animation: 600,
    disabled: props.disabled,
  }
})

const inputVisible = ref(false);
const inputValue = ref('');
const addInputRef = ref();

const handleShowAddInput = () => {
  inputVisible.value = true
  nextTick(() => {
    addInputRef.value?.input.focus()
  })
};

const handleAddInputConfirm = () => {
  let value = inputValue.value
  if (value) {
    props.dynamicTags.push({id: 0, item: value, order_num: Date.now()})
  }
  inputValue.value = ''
  inputVisible.value = false
}

const handleDelete = (tag: DynamicItem) => {
  props.dynamicTags.splice(props.dynamicTags.indexOf(tag), 1)
};
</script>

<style lang="scss" scoped>
.el-input__inner {
  padding: 0 8px !important;
}

.dynamic-item {
  display: inline-block;
  padding: 5px;
  position: relative;

  .close-icon {
    width: 16px;
    height: 16px;
    vertical-align: 2px;
    border-radius: 50%;
    text-align: center;
    transition: all .3s cubic-bezier(.645, .045, .355, 1);
    transform-origin: 100% 50%;
    font-size: 12px;
    border: 1px solid #b4bccc;
    background: var(--el-fill-color-blank);
    position: absolute;
    top: 0;
    right: 0;
    display: flex;
    align-items: center;
    justify-content: center;

    &:before {
      transform: scale(.8);
      display: inline-block;
      content: 'x';
      margin-bottom: 2px;
    }

    &:hover {
      color: var(--el-color-primary);
      border: 1px solid var(--el-color-primary);
    }
  }
}

.button-add-tag {
  vertical-align: bottom;
}

.dynamic-tag,
.dynamic-tag-add {
  max-width: v-bind(maxWidth) !important;
  vertical-align: bottom;
}
</style>
